Java基础知识(十五)

Author Avatar
子语 2017 - 11 - 11
  • 在其它设备中阅读本文章

扩展概念

匿名内部类

interface Message {
    public void print();
}

class Messagelmpl implements Message {
    public void print() {
        System.out.println("Hello");
    }
}

public class Demo {
    public static void main(String[] args) {
        fun(new Messagelmpl());
    }

    public static void fun(Message msg) {
        msg.print();
    }
}

假如Messagelmpl只使用一次,那么就可以利用匿名内部类。
范例:使用匿名内部类

interface Message {
    public void print();
}

public class Demo {
    public static void main(String[] args) {
        fun(new Message() {
            // 匿名内部类
            public void print() {
                System.out.println("Hello");
            }
        });
    }

    public static void fun(Message msg) {
        msg.print();
    }
}

使用匿名内部类的前提:必须基于接口或抽象类的应用。
匿名内部类定义在方法中,方法的参数或是变量要被匿名内部类访问,必须加上final关键字。匿名内部类的优点在于减少了类的定义。

基本数据类型的包装类

1、Java设计的基本原则:一切皆对象,一切操作都以对象的形式进行描述。此时我们发现,有一个矛盾点,基本数据类型不是对象。对于这个矛盾点,我们可以进行处理:

class MyInt { // 定义类
    private int num; // 类封装基本数据类型

    // 定义构造方法,将基本数据类型传递给对象
    public MyInt(int num) {
        this.num = num;
    }

    public int intValue() { // 返回被封装的数据
        return this.num;
    }
}

public class Demo {
    public static void main(String[] args) {
        MyInt mi = new MyInt(10); // 装箱
        int temp = mi.intValue(); // 拆箱
        // 被封装的数据只有拆箱后才能进行计算
        System.out.println(temp * 2);
    }
}

Java为了方便用户使用,专门提供了一组包装类,来包装所有的基本类型:byte(Byte)short(Short)int(Integer)long(Long)float(Float)double(Double)boolean(Boolean)char(Character)。()中为基本类型对应的包装类。

以上包装类严格讲分为两种子类型:
· 对象型包装类(Object直接子类):Character,Boolean;
· 数值型包装类(Number直接子类):Byte、Short、Integer、Float、Long、Double

Numbe是一个抽象类,一共定义了六个操作方法:byteValue()shortValue()integerValue()floatValue()longValue()doubleValue()

装箱与拆箱

1、基本数据类型与包装类间的转换通过以下方式:

· 装箱操作: 将基本数据类型变为包装类的形式:
|- 每个包装类的构造方法都可以接收各自数据类型的变量;
· 拆箱操作: 将包装类取出被包装基本数据类型数据:
|- 利用Number类中提供的一些列xxValue()方法
范例:使用int和Integer

public class Demo {
    public static void main(String[] args) {
        Integer obj = new Integer(10); // 装箱
        int temp = obj.intValue(); // 拆箱
        System.out.println(temp * 2);
    }
}

范例:使用double和Double

public class Demo {
    public static void main(String[] args) {
        Double obj = new Double(10.2); // 装箱
        double temp = obj.doubleValue(); // 拆箱
        System.out.println(temp * 2);
    }
}

范例:使用boolean和Boolean

public class Demo {
    public static void main(String[] args) {
        Boolean obj = new Boolean(true); // 装箱
        boolean temp = obj.booleanValue(); // 拆箱
        System.out.println(!temp);
    }
}

2、所有包装类都利用同种格式的方法进行操作。但在JDK1.5之后,增加了自动装箱和自动拆箱的机制,并且可以直接使用包装类的对象进行数字计算,为开发提供了便利。

public class Demo {
    public static void main(String[] args) {
        Integer obj = 10; // 自动装箱
        int temp = obj; // 自动拆箱
        obj++; // 包装类直接进行数学计算
        System.out.println(temp * obj);
    }
}

3、注意点:Integer对象可以直接赋值,也可以使用构造方法赋值,二者有何区别?
两者的区别可以参考String类直接赋值和构造方法赋值的区别。

public class Demo {
    public static void main(String[] args) {
        Integer objA = 10; // 自动装箱
        Integer objB = 10; // 自动装箱
        Integer objC = new Integer(10);
        System.out.println(objA == objB); // true
        System.out.println(objA == objC); // false
        System.out.println(objA.equals(objC)); // true
    }
}

使用包装类时,几乎都是直接赋值,很少使用构造方法,判断内容是否相等时依然使用equals()方法。
4、Object类可以接收一切引用数据类型,由于自动装箱机制的存在,Object也可以接收基本数据类型。

流程:基本数据类型 → 自动装箱(成为对象) → 向上转型为Object。

public class Demo {
    public static void main(String[] args) {
        Object obj = 10;
        // Object不能直接向下转型向int
        // Object只能自动转型为Integer
        int temp = (Integer) obj;
        System.out.println(temp * 2);
    }
}

数据类型转换

1、包装类多用于数据类型转换:在包装类中提供了将String数据变为基本数据类型的方法。
如下:

· Integer类:public static int parseInt(String s);
· Double类:public static double parseDouble(String s);
· Boolean类:public static boolean parseBoolean(String s);

注意Character类不存在将字符串变为字符的方法,但String类的charAt()可以根据索引取出字符。
范例:将String变为int型

public class Demo {
    public static void main(String[] args) {
        String str = "123";
        int temp = Integer.parseInt(str);
        System.out.println(temp * 2);
    }
}

将字符串变为int型的前提是:该字符串全部为数字.
范例:将String变为double型

public class Demo {
    public static void main(String[] args) {
        String str = "12.3";
        double temp = Double.parseDouble(str);
        System.out.println(temp * 2);
    }
}

范例:将String变为boolean

public class Demo {
    public static void main(String[] args) {
        String str = "true";
        boolean temp = Boolean.parseBoolean(str);
        System.out.println(!temp);
    }
}

Boolean转换时,如果字符串的值不是true或false,默认转为false。
2、字符串可以变为基本数据类型,基本数据类型也可变为字符串。方法有两种:
(1)任何基本数据类型与字符串使用+连接后,都会变为String类型数据

public class Demo {
    public static void main(String[] args) {
        int num = 100;
        String str = num + ""; // 变为String类
        System.out.println(str.replaceAll("0", "9")); // 199
    }
}

上述方式虽然完成了转换,但产生了垃圾""
(2)利用public static String valueOf(数据类型 变量)

public class Demo {
    public static void main(String[] args) {
        int num = 100;
        String str = String.valueOf(num);
        System.out.println(str.replaceAll("0", "9")); // 199
    }
}

上述方式不会产生垃圾,因此开发中常用上述方法。

包的定义及使用

包的定义

1、包指的是程序的目录。早期开发一个程序是将所有类写在一个java文件中,编译后程序将直接保存在根目录下。利用包可以实现程序拆分,将不同的类根据要求保存在不同目录中。
包的定义通过关键字package完成。
范例:定义包

package com.java.demo;

public class Demo {
    public static void main(String[] args) {
    }
}

2、定义包时用.表示子目录。如果类中有包的定义,就必须使其保存在对应的目录下,而这些目录不需要手动创建,可以使用命令自动生成:
(1)打包编译:java -d . Demo.java
|- -d: 根据package定义生成目录;
|-.:设置保存路径。.表示在当前路径下生成。
(2)解释程序时不要进入包中解释程序,而是在包外输入类的完整名称包.类
|- java com.java.demo.Demo

包的导入

1、使用包可以将一个完整的程序拆分为不同文件,从而分别保存。这存在问题:不同包间可能要进行互相访问,就需要进行导包操作,使用import语句完成。
范例:定义com.java.util.Message

package com.java.util;

class Message{
    public static void print(){
        System.out.println("Hello World !");
    }
}

定义com.java.test.TestMessage

package com.java.test;

import com.java..util.Message;

public class TestMessage {
    public static void print() {
        Message msg = new Message();
        msg.print();
    }
}

编译时,应先编译Message,再编译TestMessage:
|- javac -d . Message.java
|- javac -d . TestMessage.java
此时报错:Message在com.java.util中不是公共的; 无法从外部程序包中对其进行访问
出现上述问题是因为public class定义的类可以被不同的包访问;而class定义的类只能被本包所访问。因此我们要修改Message.java:

package com.java.util;

public class Message{
    public static void print(){
        System.out.println("Hello World !");
    }
}

Java编译器考虑到大型程序开发,因此可以使用通配符*java -d . *.java编译当前目录下所有java文件。
2、当要导入一个包中多个类时,可以使用import 包.*

package com.java.test;

import com.java..util.*;

public class TestMessage {
    public static void print() {
        Message msg = new Message();
        msg.print();
    }
}

import 包.*并不是导入包中所有的类,而是只导入程序所需的类,因此不用担心性能问题。
3、一个Java文件可能导入多个包,而不同包中可能存在同名的类。现假设:
·com.java.util.Message;
·com.java.demo.Message.

package com.java.demo;

public class Message {
    public static void print() {
        System.out.println("世界你好!");
    }
}

由于需要,要同时导入上述两个类:

package com.java.test;

import com.java.demo.Message;
import com.java.util.Message;

public class TestMessage {
    public static void main(String[] args) {
        Message msg = new Message();
        msg.print();
    }
}

系统报错:Error:(4, 1) java: com.java.demo.Message的 single-type-import 已定义具有相同简名的类型。为了避免该错误,在使用类时,应加上包名:

package com.java.test;

import com.java.demo.Message;
import com.java.util.Message;

public class TestMessage {
    public static void main(String[] args) {
        com.java.demo.Message msg = new com.java.demo.Message();
        Message.print();
    }
}

系统常用包

Java提供了许多程序开发包,此外还有许多第三方包。Java自带的常见系统包如下:

(1)java.lang:包含了String、Object、Integer等类,此包系统自动导入;
(2)java.lang.reflect:反射开发包;
(3)java.util:Java的工具包,提供了大量的工具类,像链表;
(4)java.util.regex:正则工具包;
(5)java.text:国际化处理程序包;
(6)java.io:进行输入、输出处理以及文件操作;
(7)java.net:网络编程开发包;
(8)java.sql:数据库程序开发包;
(9)java.applet:Applet程序开发包(已经不用了);
|-Applet指的是在网页上嵌套的程序,可以使用Applet做一些动态效果,是采用绘图的方式完成的显示。随着时间的发展,Applet程序已经不再使用了(如果要再实现同样的功能,都是用Canvas绘图)。
(10)java.awt、javax.swing:图形界面的开发包,主要功能是开发单机程序界面。
|-JDK1.0时推出了awt开发包,但是这个开发包使用了大量的windows图形函数,使Java丧失了可移植性;
|-JDK1.2时推出了javax.swing开发包,是一个轻量级(Java自己开发的,不再使用windows),所以Java更名为Java2;

jar命令

使用jar命令压缩class文件,压缩的单位为包。
无法加载
范例:定义Message.java文件

package com.java.util;

class Message{
    public static void print(){
        System.out.println("Hello World !");
    }
}

编译后会生成class文件,此时要交付给用户使用,将改包的代码压缩:jar -cvf my.jar com。生成的jar文件不能直接使用,必须配置CLASSPATH才能使用:SET CLASSPATH = .;jar包所在路径。开发中需要使用大量的第三方jar文件,都需要配置CLASSPATH,最简单的配置就是在环境变量中配置。

This blog is under a CC BY-NC-SA 3.0 Unported License
本文链接:http://yov.oschina.io/article/Java/Java Base/Java基础知识(十五)/